package com.yuan.gather.model;

import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import java.util.Comparator;

/**
 * 用于映射采集配置文件的Bean
 *
 * @author zhaoff
 */
@Getter
@Setter
public class GatherXmlBean {

    /**
     * 所有的主分类
     */
    private List<GatherXmlMainCategoryBean> mainCategory = new ArrayList<>();

    /**
     * key: itemkey value: 所属主分类
     */
    private Map<String, GatherXmlMainCategoryBean> indicatorMainMap = new HashMap<>();

    /**
     * key: itemkey value: 所属主分类
     */
    private Map<String, GatherDetail> indicatorMap = new HashMap<>();

    /**
     * 将指定主分类合并到这个主分类上
     *
     * @param newMainCategory 指定的主分类
     */
    public void merge(GatherXmlMainCategoryBean newMainCategory) {
        boolean found = false;
        for (GatherXmlMainCategoryBean item : mainCategory) {
            if (item.getName().equals(newMainCategory.getName())) {
                item.merge(newMainCategory);
                found = true;
                break;
            }
        }
        if (!found) {
            mainCategory.add(newMainCategory);
        }
    }

    /**
     * 主分类根据优先级进行排序
     */
    private void sort() {
        this.mainCategory.sort(Comparator.comparing(GatherXmlMainCategoryBean::getPriority));
    }

    /**
     * 读取xml文件成功后排序merge
     */
    public void buildComplete() {
        clear();
        sort();
        mainCategory.forEach(main -> main.listIndicators().forEach(indicator -> buildMap(main, indicator)));
    }

    /**
     * 清空所有内存变量
     */
    private void clear() {
        indicatorMainMap.clear();
        indicatorMap.clear();
    }

    /**
     * 构造所有内存变量
     *
     * @param main      主分类
     * @param indicator 监控项
     */
    private void buildMap(GatherXmlMainCategoryBean main, GatherDetail indicator) {
        indicatorMainMap.putIfAbsent(indicator.itemKey(), main);
        indicatorMap.putIfAbsent(indicator.itemKey(), indicator);
    }

    /**
     * 获取BaselineXmlMainCategoryBean
     *
     * @param itemKey 键，如CPU.CPU_load
     * @return 巡检项详情
     */
    public GatherXmlMainCategoryBean queryMainCategoryByItemKey(String itemKey) {
        return indicatorMainMap.get(itemKey);
    }

    /**
     * 获取indicatorMainMap
     *
     * @return indicatorMainMap
     */
    public Map<String, GatherXmlMainCategoryBean> getIndicatorMainMap() {
        return indicatorMainMap;
    }

    /**
     * 获取indicatorMap
     *
     * @return indicatorMap
     */
    public Map<String, GatherDetail> getIndicatorMap() {
        return indicatorMap;
    }

    /**
     * 根据dispaly 获取BaselineXmlMainCategoryBean
     *
     * @param display 显示名称
     * @return 多个BaselineXmlMainCategoryBean
     */
    public List<GatherXmlMainCategoryBean> queryMainCategoryByDisplay(String display) {
        List<GatherXmlMainCategoryBean> lists = new ArrayList<>();
        for (GatherXmlMainCategoryBean main : indicatorMainMap.values()) {
            if (main.getDisplay().endsWith(display)) {
                lists.add(main);
            }
        }
        return lists;
    }

    /**
     * 获取IndicatorDetail
     *
     * @param itemKey 键，如CPU.CPU_load
     * @return 巡检项详情
     */
    public GatherDetail queryBaselineDetail(String itemKey) {
        GatherDetail blchkDetail = indicatorMap.get(itemKey);
        if (blchkDetail == null) {
            blchkDetail = queryBaselineDetail(itemKey, true);
        }
        return blchkDetail;
    }

    /**
     * 获取IndicatorDetail
     *
     * @param itemKey 键，如CPU.CPU_load
     * @param dkey    是否有dkey
     * @return 巡检项详情, 现在只有显示的名称
     */
    private GatherDetail queryBaselineDetail(String itemKey, boolean dkey) {
        String[] keys = itemKey.split("\\.");
        String varibaleName = keys[keys.length - 1];
        GatherDetail baselineDetail = getDynamicIndicator(itemKey);
        if (baselineDetail != null && baselineDetail.getOutput() != null) {
            GatherDetailOutput detailOutput = baselineDetail.getOutput().get(0);
            for (GatherDetailVariable blchkDetailVariable : detailOutput.getVariable()) {
                if (blchkDetailVariable.getName().equals(varibaleName)) {
                    GatherDetail blchkDetail = new GatherDetail();
                    blchkDetail.setDisplay(keys[1] + "." + blchkDetailVariable.getDynamicIndicatorDisplay());
                    blchkDetail.setDisplayEn(keys[1] + "." + blchkDetailVariable.getDynamicIndicatorDisplayEn());
                    GatherGroup parentGroup = new GatherGroup();
                    parentGroup.setDisplay(keys[1]);
                    blchkDetail.setParentGroup(parentGroup);
                    return blchkDetail;
                }
            }
        }
        return null;
    }

    /**
     * 获取动态的 Indicator
     *
     * @param itemKey itemKey
     * @return Indicator
     */
    public GatherDetail getDynamicIndicator(String itemKey) {
        String[] keys = itemKey.split("\\.");
        String mainGroup = keys[0];
        for (Map.Entry<String, GatherDetail> indicatorEntry : indicatorMap.entrySet()) {
            GatherDetail baselineDetail = indicatorEntry.getValue();
            if (mainGroup.equals(baselineDetail.getDkey())) {
                return baselineDetail;
            }
        }
        return null;
    }

    /**
     * 获取BaselineXmlCategoryBean
     *
     * @param mainCategory 主类，如host
     * @return 巡检项详情
     */
    public GatherXmlMainCategoryBean queryMainCategory(String mainCategory) {
        for (GatherXmlMainCategoryBean m : this.mainCategory) {
            if (m.getName().equals(mainCategory)) {
                return m;
            } else if (m.getName().contains(",")) {
                String[] names = m.getName().split(",");
                for (String name : names) {
                    if (name.trim().equals(mainCategory)) {
                        return m;
                    }
                }
            }
        }
        return null;
    }

    /**
     * 获取BaselineXmlCategoryBean
     *
     * @param category 次类
     * @return 巡检项详情
     */
    public GatherXmlCategoryBean queryCategory(String category) {
        for (GatherXmlMainCategoryBean m : this.mainCategory) {
            if (m.getCategory() == null) {
                continue;
            }
            for (GatherXmlCategoryBean c : m.getCategory()) {
                if (category.equalsIgnoreCase(c.getName())) {
                    return c;
                }
            }
        }
        return null;
    }
}
